package com.wangyadong.hobby.schedule.jobtask.dsa.lesson1;

import org.openjdk.jmh.annotations.*;
import org.openjdk.jmh.runner.Runner;
import org.openjdk.jmh.runner.RunnerException;
import org.openjdk.jmh.runner.options.Options;
import org.openjdk.jmh.runner.options.OptionsBuilder;

import java.util.concurrent.TimeUnit;

/**
 * <p>
 *
 * @author <714037465@qq.com>
 * @since 2019/1/815:02
 * <p>
 * We study several sorting algorithms in this book, most of which are described in
 * Chapter 12.
 * 每次只考虑一个节点，放置每个节点到正确的位置
 * 我们从第一个节点开始，这是一个很普通的分类，当我们考虑下一个节点的时候，
 * 如果小于第一个节点，交换位置
 * 我们继续考虑第三个节点
 **/
@BenchmarkMode(Mode.SampleTime)
//@Warmup(iterations = 3)
@Measurement(iterations = 4)
@State(Scope.Thread)
@OutputTimeUnit(TimeUnit.MILLISECONDS)
public class InsertionOrderExample {

    @State(Scope.Benchmark)
    public static class Data {
        public Character[] data = {23, 45, 12, 4, 'C', 'B', 'A'};


    }


    public static void main(String[] args) throws RunnerException {
//        char[] chars = {23, 45, 12, 4, 'C', 'B', 'A'};
//        char[] chars1 = insertionSort(chars);
//        for (int i = 0; i < chars1.length; i++) {
//            System.out.println("===============" + chars1[i]);
//        }

        Options build = new OptionsBuilder()
                .include(InsertionOrderExample.class.getSimpleName())
                .forks(1)
                .build();
        new Runner(build).run();
    }

    /**
     * @param datas
     * @return
     */
    @Benchmark
    public static Character[] insertionSort(Data datas) {
        Character[] data = datas.data;
        int length = data.length;
        for (int k = 1; k < length; k++) {
            //begin with second character
            char cur = data[k];
            int j = k;
            while (j > 0 && data[j - 1] > cur) {
                data[j] = data[j - 1];
                j--;
            }
            data[j] = cur;
        }
        return data;
    }

    /**
     * @param datas
     * @return
     */
    @Benchmark
    public static Comparable[] sort(Data datas) {
        Comparable[] data = datas.data;
        int length = data.length;
        for (int i = 1; i < length; i++) {
            for (int j = i; j > 0 && data[j].compareTo(data[j - 1]) == -1; j--) {
                Comparable comparable = data[j];
                data[j] = data[j - 1];
                data[j - 1] = comparable;
            }
        }
        return data;
    }

}
